﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Labthink.PCSoft.UniversalHost4.Model.TempCtrl;
using Labthink.PCSoft.UniversalHost4.Utility;
using Newtonsoft.Json;

namespace Labthink.PCSoft.UniversalHost4.UserControls
{
    public partial class UcTempCtrl
    {
        private static readonly DispatcherTimer TempTimer = new DispatcherTimer();

        private List<TpctParam> _channels;
        private TpctParam _currentParam;
        private NotifyManager _notify;
        private bool _isLoad;

        public UcTempCtrl()
        {
            InitializeComponent();
            TempTimer.Interval = TimeSpan.FromSeconds(2);
        }

        public string Title { get; set; } = LanguageManager.GetLanguageValue("TempControllerSetting");

        public string PermissionCode { get; set; } = "Per_TempCtrl";

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetCursorPos(out POINT pt);

        private void TempCtrl_OnLoaded(object sender, RoutedEventArgs e)
        {
            var w = Window.GetWindow(this);
            _notify = NotifyManager.InstanceManager(w);

            TempTimer.Tick += TempTimerEvent;

            if (_isLoad) return;
            _isLoad = true;
            LoadTempCtrlInfo();
        }

        private async void LoadTempCtrlInfo()
        {
            _triggerButtonsStatus(false);

            var sd = await Common.Instrument.Commands.GetTempCtrlInfoAsync();

            if (sd.ErrorCode < 0)
            {
                //MessageBox.Show(sd.ErrorMsg);
                _notify.ShowError(sd.ErrorMsg);
            }
            else
            {
                if (!string.IsNullOrEmpty(sd.Value))
                {
                    _channels = JsonConvert.DeserializeObject<List<TpctParam>>(sd.Value);

                    if (_channels == null || _channels.Count == 0)
                    {
                        _triggerButtonsStatus(true);
                        return;
                    }

                    sd = await Common.Instrument.Commands.GetTempAsync();
                    var tpcts = JsonConvert.DeserializeObject<List<Tpct>>(sd.Value);
                    CbTempControllers.ItemsSource = tpcts;
                    CbTempControllers.DisplayMemberPath = "Name";
                    CbTempControllers.SelectedValuePath = "Index";
                    CbTempControllers.SelectedIndex = 0;

                    sd = await Common.Instrument.Commands.GetTempCtrlFunAsync();
                    var action = JsonConvert.DeserializeObject<List<ParamValue>>(sd.Value);
                    CbControlledItems.ItemsSource = action;
                    CbControlledItems.DisplayMemberPath = "Name";
                    CbControlledItems.SelectedValuePath = "Umc";
                    CbControlledItems.SelectedIndex = 0;
                    if (action == null || action.Count == 0)
                    {
                        GbAction.Visibility = Visibility.Collapsed;
                    }

                    TempTimer.Start();
                }
            }

            _triggerButtonsStatus(true);
        }

        private async void BtnReadParam_OnClick(object sender, RoutedEventArgs e)
        {
            if (!(CbTempParams.SelectedItem is ParamValue tv))
                return;

            if (_currentParam == null)
                return;

            _triggerButtonsStatus(false);
            TbParamValue.Text = "";
            _currentParam.CurrentParamId = tv.ParamId;
            var sd = await Common.Instrument.Commands.GetTempParamValueAsync(_currentParam);
            if (sd.ErrorCode < 0)
            {
                //MessageBox.Show(sd.ErrorMsg);
                _notify.ShowError(sd.ErrorMsg);
            }
            else
            {
                _notify.ShowSuccess(sd.ErrorMsg);
            }

            TbParamValue.Text = sd.Value.ToDouble().Round(2);
            _triggerButtonsStatus(true);
        }

        private async void BtnSetParam_OnClick(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(TbParamValue.Text))
            {
                //MessageBox.Show(LanguageManager.GetLanguageValue("DataEmpty_TempParamValue"));
                _notify.ShowError(LanguageManager.GetLanguageValue("DataEmpty_TempParamValue"));
                return;
            }

            if (!TbParamValue.Text.IsNumeric())
            {
                //MessageBox.Show(LanguageManager.GetLanguageValue("DataError_TempParamValue"));
                _notify.ShowError(LanguageManager.GetLanguageValue("DataError_TempParamValue"));
                return;
            }

            if (string.IsNullOrEmpty(TbParamValue.Text)) return;
            if (!(CbTempParams.SelectedItem is ParamValue tv)) return;
            if (_currentParam == null) return;
            _triggerButtonsStatus(false);
            //tv.Value = txtParamValue.Text.ToDouble();
            _currentParam.CurrentParamId = tv.ParamId;
            _currentParam.Params.Single(p => p.ParamId == tv.ParamId).Value = TbParamValue.Text.ToDouble();
            var sd = await Common.Instrument.Commands.SetTempParamValueAsync(_currentParam);
            if (sd.ErrorCode < 0)
            {
                //MessageBox.Show(sd.ErrorMsg);
                _notify.ShowError(sd.ErrorMsg);
            }
            else
            {
                _notify.ShowSuccess(sd.ErrorMsg);
            }

            _triggerButtonsStatus(true);
        }

        private async void BtnOpen_OnClick(object sender, RoutedEventArgs e)
        {
            if (!(CbControlledItems.SelectedItem is ParamValue pv)) return;
            _triggerButtonsStatus(false);

            pv.Value = 1;
            var sd = await Common.Instrument.Commands.SetTempControlledItemStatusAsync(pv);

            if (sd.ErrorCode < 0)
            {
                //MessageBox.Show(sd.ErrorMsg);
                _notify.ShowError(sd.ErrorMsg);
            }
            else
            {
                _notify.ShowSuccess(sd.ErrorMsg);
            }
            _triggerButtonsStatus(true);
        }

        private async void BtnClose_OnClick(object sender, RoutedEventArgs e)
        {
            if (!(CbControlledItems.SelectedItem is ParamValue pv)) return;
            _triggerButtonsStatus(false);

            pv.Value = 0;
            var sd = await Common.Instrument.Commands.SetTempControlledItemStatusAsync(pv);

            if (sd.ErrorCode < 0)
            {
                //MessageBox.Show(sd.ErrorMsg);
                _notify.ShowError(sd.ErrorMsg);
            }
            else
            {
                _notify.ShowSuccess(sd.ErrorMsg);
            }
            _triggerButtonsStatus(true);
        }

        private void cbTempControllers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var tpct = CbTempControllers.SelectedItem as Tpct;
            RbChannel1.Visibility = Visibility.Collapsed;
            RbChannel2.Visibility = Visibility.Collapsed;
            RbChannel3.Visibility = Visibility.Collapsed;
            RbChannel4.Visibility = Visibility.Collapsed;
            if (tpct != null)
            {
                var tps = _channels.Where(t => t.Type == tpct.Type && t.Index == tpct.Index).ToList();
                if (tps.Count > 0)
                {
                    RbChannel1.IsChecked = false;
                    RbChannel1.Visibility = Visibility.Visible;
                    RbChannel1.Tag = tps[0];
                    RbChannel1.Content = tps[0].Name;
                    RbChannel1.IsChecked = true;
                    _currentParam = tps[0];
                }
                if (tps.Count > 1)
                {
                    RbChannel2.Visibility = Visibility.Visible;
                    RbChannel2.Tag = tps[1];
                    RbChannel2.Content = tps[1].Name;
                    //radioButton2.Checked = true;
                }
                if (tps.Count > 2)
                {
                    RbChannel3.Visibility = Visibility.Visible;
                    RbChannel3.Tag = tps[2];
                    RbChannel3.Content = tps[2].Name;
                }
                if (tps.Count > 3)
                {
                    RbChannel4.Visibility = Visibility.Visible;
                    RbChannel4.Tag = tps[3];
                    RbChannel4.Content = tps[3].Name;
                }
            }
        }

        private void rbChannel_Checked(object sender, RoutedEventArgs e)
        {
            var rb = sender as RadioButton;
            if (rb?.IsChecked != null && rb.IsChecked.Value)
            {
                if (rb.Tag is TpctParam tp)
                {
                    CbTempParams.ItemsSource = tp.Params.Where(p => !string.IsNullOrEmpty(p.Name));
                    CbTempParams.DisplayMemberPath = "Name";
                    CbTempParams.SelectedValuePath = "Umc";
                    CbTempParams.SelectedIndex = 0;
                    _currentParam = tp;
                    LblTemp.Content = tp.Name;
                    TxtUnit.Text = tp.ShowUnit;
                }
                TbTemperature.Text = string.Empty;
            }
        }

        public async void TempTimerEvent(object sender, EventArgs e)
        {
            if (_currentParam == null) return;
            var sd = await Common.Instrument.Commands.GetRealtimeTempAsync(_currentParam.Umc);
            TbTemperature.Text = sd.Value.Round(1) + "";
        }

        private void _triggerButtonsStatus(bool status)
        {
            if (status)
            {
                BtnReadParam.IsEnabled = true;
                BtnSetParam.IsEnabled = true;
                BtnOpen.IsEnabled = true;
                BtnClose.IsEnabled = true;
                Loading.Visibility = Visibility.Collapsed;
            }
            else
            {
                BtnReadParam.IsEnabled = false;
                BtnSetParam.IsEnabled = false;
                BtnOpen.IsEnabled = false;
                BtnClose.IsEnabled = false;
                Loading.Visibility = Visibility.Visible;
            }
        }
        private void Txt_OnGotFocus(object sender, RoutedEventArgs e)
        {
            
        }

        private void Txt_OnLostFocus(object sender, RoutedEventArgs e)
        {
            if (!Txt1.IsFocused) pop1.StaysOpen = false;
        }

        private void Txt_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            pop1.IsOpen = false;
            pop1.IsOpen = true;
            pop1.StaysOpen = false;
            pop1.StaysOpen = true;
            Txt1.Text = TbParamValue.Text;
        }

        private void Txt_OnPreviewTouchDown(object sender, TouchEventArgs e)
        {
            pop1.IsOpen = false;
            pop1.IsOpen = true;
            pop1.StaysOpen = false;
            pop1.StaysOpen = true;
        }

        private void _openInput(FrameworkElement fe)
        {
       
        }

        private bool _isOpen()
        {
         
            return true;
        }

        private void UcTempCtrl_OnUnloaded(object sender, RoutedEventArgs e)
        {
            TempTimer.Stop();
            TempTimer.Tick -= TempTimerEvent;
        }

        private void Txt_OnTextChanged(object sender, TextChangedEventArgs e)
        {
            if (sender is TextBox txt)
            {
                if (txt.Text != TbParamValue.Text) TbParamValue.Text = txt.Text;
                if (txt.Text != Txt1.Text) Txt1.Text = txt.Text;
            }
        }

        private void Txt1_OnLostFocus(object sender, RoutedEventArgs e)
        {
            pop1.StaysOpen = false;
            pop1.IsOpen = false;
        }
    }
}
